package com.competition.web.admin.service.impl;

import java.util.concurrent.TimeUnit;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.competition.web.admin.config.AdminInfo;
import com.competition.web.admin.mapper.LogMapper;
import com.competition.web.admin.service.ILogService;
import com.basic.service.impl.BaseServiceImpl;
import com.competition.web.admin.util.RequestUtil;
import com.competition.web.constant.Const;
import com.competition.web.constant.RedisConstant;
import com.dao.base.IBaseMapper;
import com.security.admin.security.util.JwtTokenUtil;
import com.competition.web.entity.Log;
import com.competition.web.entity.TableComment;

@Service
public class LogServiceImpl extends BaseServiceImpl<Log> implements ILogService {

	
	
	private JwtTokenUtil jwtTokenUtil;

	private RedisTemplate<String, Object> redisTemplate;
	
	private AdminInfo adminInfo;
	

	@Autowired
	public void setRedisTemplate(RedisTemplate<String, Object> redisTemplate) {
		this.redisTemplate = redisTemplate;
	}

	final int CERTIFICATE_CLASSIFICATION = 1;

	public LogServiceImpl(LogMapper mapper) {
		super(mapper);
	}


	protected void insertPropteris(Log data) {

		int time = (int) (System.currentTimeMillis() / 1000);

		data.setCreateTime(time);
	}




	public Log selectByPrimaryKey(int id) {

		String key = RedisConstant.getCertificateKey(id);

		ValueOperations<String, Object> valueOperations = this.redisTemplate.opsForValue();

		Log competitionInfo = (Log) valueOperations.get(key);

		if (null != competitionInfo) {
			return competitionInfo;
		}

		competitionInfo = super.selectByPrimaryKey(id);

		if (null == competitionInfo) {
			competitionInfo = new Log();
		}

		valueOperations.set(key, competitionInfo, 5, TimeUnit.SECONDS);

		return competitionInfo;

	}
	
	protected TableComment getTableComment(String tableName) {
		
		String key = RedisConstant.getTableCommentKey(tableName);

		ValueOperations<String, Object> valueOperations = this.redisTemplate.opsForValue();

		TableComment tableComment = (TableComment) valueOperations.get(key);

		if (null != tableComment) {
			return tableComment;
		}

		LogMapper logMapper = this.getBaseMapper();
		
		tableComment = logMapper.getTableComment(tableName, Const.DATA_BASE_NAME);

		if (null == tableComment) {
			tableComment = new TableComment();
		}

		valueOperations.set(key, tableComment, 50, TimeUnit.SECONDS);

		return tableComment;
		
	}
	

	@Override
	public int insertParse(Log log, String tableName, Byte type) {
		
		return this.insert(this.getLog(log, tableName, type));
	}
	
	protected Log getLog(Log log, String tableName, Byte type) {
		
		TableComment comment = this.getTableComment(tableName);
		
		log.setComment(comment.getTableComment());
		
		log.setType(type);
		
		log.setTableName(tableName);

		log.setId(0L);
		
		ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
		
		HttpServletRequest request = attributes == null ? null: attributes.getRequest();
		
		
		
//		String token = this.adminInfo.getId();//request.getHeader("Authorization");
		
		log.setAdminId(this.adminInfo.getId().longValue()/* jwtTokenUtil.getId(token) */);
		
		log.setIp(RequestUtil.getRequestIp(request));
		
		return log;
	}
	
	

	public int batchInsertParse(Log[] list, String tableName, Byte type) {
		
		for (int i = 0; i < list.length; i++) {
			
			list[i] = this.getLog(list[i], tableName, type);
		}
		
		return super.batchInsert(list);
	}

	public JwtTokenUtil getJwtTokenUtil() {
		return jwtTokenUtil;
	}

	@Autowired
	public void setJwtTokenUtil(JwtTokenUtil jwtTokenUtil) {
		this.jwtTokenUtil = jwtTokenUtil;
	}

	@Resource
	public void setAdminInfo(AdminInfo adminInfo) {
		this.adminInfo = adminInfo;
	}

}